/**
 * @file OLED.c
 * @author your name (you@domain.com)
 * @brief OLED驱动源文件
 * @version 0.1
 * @date 2024-03-31
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "OLED.h"
#include "OLED_Font.h"
/**
 * @brief 向OLED发送命令
 * 
 * @param Cmd 命令
 */
void OLED_WriteCmd(uint8_t Cmd)
{
    IIC_Per_WriteReg(I2C1,OLED_Address,OLED_CmdAdr,Cmd);
}

/**
 * @brief 向OLED连续发送命令
 * 
 * @param Cmd 命令数组
 * @param Length 数组长度
 */
void OLED_WriteCmd_Coiled(uint8_t* Cmd,uint16_t Length)
{
    IIC_Per_WriteReg_Coiled(I2C1,OLED_Address,OLED_CmdAdr,Cmd,Length);
}

/**
 * @brief 向OLED发送数据
 * 
 * @param Data 数据
 */
void OLED_WriteData(uint8_t Data)
{
    IIC_Per_WriteReg(I2C1,OLED_Address,OLED_DataAdr,Data);
}


/**
 * @brief 向OLED连续发送数据
 * 
 * @param Data 数据数组
 * @param Length 数组长度
 */
void OLED_WriteData_Coiled(uint8_t* Data,uint16_t Length)
{
    IIC_Per_WriteReg_Coiled(I2C1,OLED_Address,OLED_DataAdr,Data,Length);
}


/**
 * @brief 设置显示坐标
 * 
 * @param Y Y坐标
 * @param X X坐标
 */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
    uint8_t local[3];
    local[0] = 0XB0 | Y;//设置Y坐标
    local[1] = (0X00 | (0X0F & X));//设置x坐标低四位
    local[2] = (0x10 | ((0xf0 & X) >> 4));//设置x坐标高四位
    OLED_WriteCmd_Coiled(local,3);
}

/**
 * @brief OLED初始化函数
 * 
 */
void OLED_Init(void)
{
    Delay_ms(10);//延时等待屏幕上电完成
    uint8_t OLED_InitArr[28] = {
    0XAE,0X20,0X10,0XB0,0XC8,0X00,0X10,0X40,0X81,0XDF,0XA1,0XA6,0XA8,0X3F,0XA4,0XD3,
    0X00,0XD5,0XF0,0XD9,0X22,0XDA,0X12,0XDB,0X20,0X8D,0X14,0XAF
    };


    OLED_WriteCmd_Coiled(OLED_InitArr,28);


}

/**
 * @brief OLED清屏
 * 
 */
void OLED_Clear(void)
{
    uint8_t i,j;
    for ( i = 0; i < 8; i++)
    {
        OLED_SetCursor(i,0);
        for ( j = 0; j < 128; j++)
        {
            OLED_WriteData(0x00);
        }
        
    }
    
}


/**
 * @brief OLED显示单个字符
 * 
 * @param Line 显示行数
 * @param Column 显示列数
 * @param Char 要显示的字符
 */
void OLED_Show_Char_8x16(uint8_t Line,uint8_t Column,char Char)
{
    uint8_t i;
    for ( i = 0; i < 2; i++)
    {
        OLED_SetCursor((Line-1) * 2 + i , (Column-1) * 8);
        OLED_WriteData_Coiled(&OLED_ASCII[Char][i*8],8);
    }
    
}

/**
 * @brief OLED显示字符串
 * 
 * @param Line 起始行数
 * @param Colum 起始列数
 * @param String 要显示的字符串
 */
void OLED_Show_String(uint8_t Line,uint8_t Colum,char* String)
{
    uint8_t i = 0;
    while (*(String+i) != '\0')
    {
        OLED_Show_Char_8x16(Line,Colum+i,*(String+i)-' ');
        i++;
    }
    
}

/**
 * @brief 计算次方
 * 
 * @param Cardinal 基数
 * @param Pow 指数
 * @return uint32_t 计算结果
 */
uint32_t OLED_Num_Pow(uint32_t Cardinal,uint8_t Pow)
{
    uint32_t i = 1;
    
    while (Pow != 0)
    {
        i *= Cardinal;
        Pow--;
    }
    return i;
}

/**
 * @brief OLED显示无符号整数
 * 
 * @param Line 起始行数
 * @param Column 起始列数
 * @param Show_Num 要显示的数字
 * @param Length 数字长度（不超过9）
 */
void OLED_Show_Num(uint8_t Line,uint8_t Column,uint32_t Show_Num,uint8_t Length)
{
    uint8_t i;
    if (Length > 9)
    {
        Length = 9;
    }
    
    uint32_t dev = OLED_Num_Pow(10,Length);
    for ( i = 0; i < Length; i++)
    {
        Show_Num %= dev;
        dev /= 10;
        OLED_Show_Char_8x16(Line,Column+i,Show_Num/dev%10+16);
    }
    
}

/**
 * @brief OLED显示有符号整数
 * 
 * @param Line 起始行数
 * @param Column 起始列数
 * @param ShowNum 要显示的数字
 * @param Length 数字长度（不超过9）
 */
void OLED_Show_SignNum(uint8_t Line,uint8_t Column,int32_t ShowNum,uint8_t Length)
{
    if (ShowNum < 0)
    {
        OLED_Show_Char_8x16(Line,Column,'-'-' ');
        ShowNum = 0 - ShowNum;
    }
    else
    {
        OLED_Show_Char_8x16(Line,Column,'+'-' ');
    }
    OLED_Show_Num(Line,Column+1,(uint32_t)ShowNum,Length);
}

/**
 * @brief OLED显示小数
 * 
 * @param Line 起始行数
 * @param Column 起始列数
 * @param Show_Num 要显示的数字
 * @param Z_Length 整数部分长度（不超过9）
 * @param F_Length 小数部分长度（不超过9）
 */
void OLED_Show_PointNum(uint8_t Line,uint8_t Column,float Show_Num,uint8_t Z_Length,uint8_t F_Length)
{
    uint32_t temp;
    temp = (uint32_t)Show_Num;
    float roundingOffset = 0.5 / OLED_Num_Pow(10, F_Length+1);
    OLED_Show_Num(Line,Column,temp,Z_Length);
    OLED_Show_Char_8x16(Line,Column+Z_Length,'.' - ' ');
    temp = (uint32_t)(OLED_Num_Pow(10,F_Length)*(Show_Num-temp+roundingOffset));
    OLED_Show_Num(Line,Column+1+Z_Length,temp,F_Length);
    
    
}
